package com.zisuyi.uilibrary.view

import android.content.Context
import android.graphics.Color
import android.graphics.Typeface
import android.graphics.drawable.Drawable
import android.util.AttributeSet
import android.view.Gravity
import android.view.View
import android.view.animation.AccelerateDecelerateInterpolator
import androidx.annotation.DrawableRes
import androidx.core.content.ContextCompat
import com.weilele.mvvm.utils.activity.dip
import com.weilele.mvvm.utils.disEnableSystemAnimDurationScale
import com.weilele.mvvm.widget.BaseConstraintLayout
import com.weilele.mvvm.widget.BaseImageView
import com.zisuyi.uilibrary.R


class BaseSpinView : BaseConstraintLayout {
    private lateinit var spinBackground: Drawable
    private val rootViewId = View.generateViewId()
    private val itemViewList = mutableListOf<View>()
    private val itemDataList = mutableListOf<SpinBean>()

    //当前item一份有多少角度
    private var spanOff: Float = 0f

    //转盘是否正在旋转
    private var isSpinRun = false
    val isSpinGameRun: Boolean
        get() = isSpinRun

    //当前连续游戏次数
    var gameCountNumber = 0
    private var spinGameCompleteListener: Function1<SpinBean, Unit>? = null

    //转盘背景
    private val bgView by lazy {
        val bg = BaseImageView(context)
        bg.id = View.generateViewId()
        val lp = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
        addView(bg, lp)
        bg
    }

    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    ) {
        if (id == View.NO_ID) {
            id = rootViewId
        }
        context?.apply {
            val typedArray = obtainStyledAttributes(attrs, R.styleable.BaseSpinView)
            typedArray.getDrawable(R.styleable.BaseSpinView_spinBackground)?.let {
                spinBackground = it
                setSpinBackground(spinBackground)
            }
            typedArray.recycle()
        }
    }

    fun setSpinBackground(@DrawableRes drawable: Int) {
        setSpinBackground(ContextCompat.getDrawable(context, drawable)!!)
    }

    fun setSpinBackground(drawable: Drawable) {
        spinBackground = drawable
        bgView.setImageDrawable(spinBackground)
    }

    /**
     * 创建一个转盘选项
     */
    private fun createSpinItem(spinBean: SpinBean, rotationView: Float) {
        val spanHalf = spinBean.span * spanOff / 2
        spinBean.startAngle = rotationView - spanHalf
        spinBean.endAngle = rotationView + spanHalf
        val viewHeight = spinBackground.intrinsicHeight.div(2)
        val viewWidth = dip(40)
        val lp = LayoutParams(viewWidth, viewHeight)
        val item = spinBean.customView ?: FontTextView(context).apply {
            gravity = Gravity.CENTER
            text = spinBean.name
            textSize = 20f
            setTextColor(Color.parseColor("#EC23FF"))
        }
        item.apply {
            lp.startToStart = this@BaseSpinView.id
            lp.topToTop = this@BaseSpinView.id
            lp.endToEnd = this@BaseSpinView.id
            pivotX = viewWidth.toFloat() / 2
            pivotY = viewHeight.toFloat()
            rotation = rotationView
        }
        itemViewList.add(item)
        addView(item, lp)
    }

    /**
     * 每个字符串后面加个换行，实现竖向文字
     */
    private fun handlerText(name: String): String {
        val sb = StringBuffer()
        sb.append("\n")
        name.forEach {
            sb.append(it)
            sb.append("\n")
        }
        return sb.toString()
    }

    fun setSpinData(dataList: List<SpinBean>) {
        itemViewList.forEach {
            removeView(it)
        }
        itemViewList.clear()
        itemDataList.clear()
        itemDataList.addAll(dataList)
        //总数
        var allCount = 0
        dataList.forEach {
            allCount += it.span
        }
        if (allCount == 0) {
            return
        }
        //一份span应该有多少角度
        spanOff = 360f / allCount
        var rotationSpan = 0
        val firstItemSpan = dataList[0].span * spanOff
        dataList.forEachIndexed { index, spinBean ->
            val offRotation = spinBean.span * spanOff / 2
            createSpinItem(
                spinBean,
                rotationSpan * spanOff + offRotation - firstItemSpan / 2/*由于第一个不旋转，所以需要减掉第一个需要旋转的角度*/
            )
            rotationSpan += spinBean.span
        }
    }

    /**
     * 开始旋转，这里旋转的是底盘，而不是指针
     * 指针默认向上
     * index 旋转到哪个item停下来,0为第一个
     * repeatCount 旋转几圈
     * rotationView:指针，不为null，则旋转指针
     */

    fun startSpin(
        position: Int,
        gameCompleteListener: Function1<SpinBean, Unit>,
        rotationView: View? = null,
        repeatCount: Int = 5
    ) {
        if (isSpinRun) {
            return
        }
        if (position in 0 until itemDataList.count()) {
            spinGameCompleteListener = gameCompleteListener
            isSpinRun = true
            gameCountNumber++
            val spinBean = itemDataList[position]
            val startAngle = spinBean.startAngle
            //为了仿真生成随机数，随机停留在指定的position内
            val stopAngle = Math.random() * (spinBean.endAngle - startAngle) + startAngle
            val view = rotationView ?: this
            val allRotation =
                if (rotationView == null)
                //底盘旋转
                    repeatCount * 360f * gameCountNumber - stopAngle.toFloat()
                else
                //指针旋转
                    repeatCount * 360f * gameCountNumber + stopAngle.toFloat()
            view.animate().rotation(allRotation)
                .setInterpolator(AccelerateDecelerateInterpolator())
                .setDuration(4000)
                .withEndAction {
                    isSpinRun = false
                    spinGameCompleteListener?.invoke(spinBean)
                }
                .start()
            view.animate().disEnableSystemAnimDurationScale()
        }
    }

    /**
     * 重新设置游戏
     */
    fun resetGame() {
        rotation = 0f
        gameCountNumber = 0
    }


    data class SpinBean(
        val name: String?,
        val span: Int = 1,
        var customView: View? = null
    ) {
        var startAngle: Float = 0f
        var endAngle: Float = 0f
    }
}